<!doctype html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>文件上传 - 虎绿林</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <!--[if lt IE 8]><script src="../../js/json3/lib/json3.min.js"></script><![endif]-->
    <!--[if lt IE 9]><script src="../../js/js-polyfills/es5.js"></script><![endif]-->
    <!--[if lt IE 10]><script src="../../js/moxie/bin/js/moxie.min.js"></script><![endif]-->
    <script src="../../js/jquery-3.1.1.min.js"></script>
    <script src="../../js/bce-bos-uploader/bce-bos-uploader.bundle.min.js?r=1"></script>
    <script src="../../js/humanize/humanize.js"></script>
    <link rel="stylesheet" type="text/css" href="../../css/default.css?r=202206160501" />
    <link rel="stylesheet" type="text/css" href="../../css/new.css?r=202206160501" />
    <script src="../../js/hu60/header.js"></script>
    <style>
        p {
            margin: 2px;
            padding: 0;
        }
        #file_list .file_box {
            padding: 5px 10px;
            border: solid #BED8EA 1px;
            border-bottom: none;
        }
        #file_list .box_title {
            display: inline-block;
            width: 60px;
            text-align: right;
            padding-right: 10px;
        }
        #file_list .box_action {
            padding-left: 10px;
        }
        #content {
            width: 99%;
            height: 200px;
            max-width: 100%;
        }
        #file_selector {
            margin-bottom: 5px;
        }
        #desc, #topic_content, #file_selector, #legacy_mode_bar {
            text-align: center;
        }
        #to_modern_mode, #legacy_mode_form {
            display: none;
            margin-top: 10px;
        }
    </style>
</head>
<body id="file_drop_area">
<div id="desc" class="tp">
    <p>文件保存在虎绿林的 BCE BOS 云存储中，任何人都可以查看。</p>
    <p>若空间占用过大，老文件可能会被删除，请不要保存重要内容。</p>
    <p>可一次上传多个文件，若浏览器不支持多选，可以分多次添加。</p>
    <p>也可直接拖放或粘贴文件，电脑截图后可按Ctrl+V直接粘贴。</p>
</div>
<hr>
<div id="topic_content">
    <textarea id="content"></textarea>
</div>
<hr>
<div id="file_selector" class="tp">
    <input type="file" id="file" />
    <input type="button" id="upload" value="上传" disabled />
    <input type="button" id="save" value="暂存" />
    <input type="button" id="load" value="载入" />
    <input type="button" id="finish" value="完成" />
    <span id="action_state"></span>
</div>
<div id="upload_state_bar"></div>
<div id="file_list"></div>
<hr>
<div id="legacy_mode_bar">
    <p id="to_legacy_mode">总是上传失败？<a href="#" onclick="fileList.legacyMode();return false">切换到传统模式。</a></p>
    <form id="legacy_mode_form" action="/q.php/bbs.upload.html" method="post" enctype="multipart/form-data">
        <input type="file" id="legacy_mode_file" name="file" />
        <input type="button" id="legacy_mode_upload" name="go" value="上传" />
    </form>
    <p id="to_modern_mode">传统模式不好用？<a href="#" onclick="fileList.legacyMode();return false">切换到现代模式。</a></p>
</div>
<hr>
<div class="tp">
    <p id="date">
        0月0日 00:00 星期零
    </p>
    <p>
        效率: 0秒（这是一个静态页面）
    </p>
    <p id="hu60_footer_action">
        [<a href="javascript:fileList.back()">返回上级</a>]
        [<a href="/q.php/index.index.html">首页</a>]
        [<a href="javascript:scroll(0,0)">回顶</a>]
    </p>
    <p>
        本站由 <a href="https://gitee.com/hu60t/hu60wap6">hu60wap6</a> 驱动
    </p>
    <p>[<a href="/q.php/addin.chat.文件上传.html">聊天-文件上传</a>]老虎会游泳：有问题可以进入这个聊天室反馈。</p>
</div>
<script>
    function htmlSpecialChars(str) {
        str = str.replace(/&/g, '&amp;');
        str = str.replace(/</g, '&lt;');
        str = str.replace(/>/g, '&gt;');
        str = str.replace(/"/g, '&quot;');
        str = str.replace(/'/g, '&#039;');
        return str;
    }
    var fileList = {
        topic: {}, //保存的帖子内容
        fidCounter: 0, //文件id计数器
        uploadedFiles: [], //保存已上传完成的file对象，格式：['1'=> file, '2'=> file, ...]，key为fid
        /**
         * 返回上级
         */
         back: function() {
            var url = fileList.topic.url;
            if (!url) {
                alert('无法返回来源页面，请自行复制内容并粘贴到发言框。');
                return;
            }
            fileList.topic.url = undefined;
            fileList.topic.content = $('#content').val();
            document.location = url + '#addfiles=' + encodeURIComponent(JSON.stringify(fileList.topic));
        },
        fileUploaded: function (file){
            this.uploadedFiles[file._id] = file;
        },
        setFid: function (file) {
            file._id = ++this.fidCounter;
        },
        add: function (file) {
            $('#file_list').append('<div id="upload_fid_' + file._id + '" class="file_box">' +
                    '<p class="file_name"><span class="box_title">文件名</span><span class="box_value">' + htmlSpecialChars(file.name) + '</span></p>' +
                    '<p class="file_size"><span class="box_title">大小</span><span class="box_value">' + humanize.filesize(file.size) + '</span>' +
                        '<span class="uploaded_size"></span></p>' +
                    '<p class="file_state"><span class="box_title">状态</span><span class="box_value">-</span>' +
                        '<span class="box_action"><a href="#" onclick="fileList.remove('+file._id+',\''+file.uuid+'\');return false">取消</a></span></p>' +
                    '<p class="file_progress"><span class="box_title">进度</span><span class="box_value">0%</span></p>' +
                '</div>');
            $('#upload').removeAttr('disabled');
        },
        remove: function (fid, uuid) {
            uploader.remove(uuid);

            $('#upload_fid_' + fid).fadeOut("normal", function (){
                $(this).remove();
            });
        },
        setState: function (fid, state) {
            $('#upload_fid_' + fid + ' .file_state .box_value').html(state);
        },
        setAction: function (fid, state) {
            $('#upload_fid_' + fid + ' .file_state .box_action').html(state);
        },
        setProgress: function (fid, progress) {
            $('#upload_fid_' + fid + ' .file_progress .box_value').html((progress * 100).toFixed(2) + '%');

            if (1 == progress) {
                this.setState(fid, "确认中...");
            }
        },
        setSpeed: function (bytes, time, pendings) {
            var speed = bytes / (time / 1000);
            var html = '上传速度：' + humanize.filesize(speed) + '/s';
            var seconds = pendings / speed;
            if (seconds > 1) {
                var dhms = baidubce.utils.toDHMS(~~seconds);
                html += '，剩余时间：' + [
                            humanize.pad(dhms.HH, 2, '0'),
                            humanize.pad(dhms.MM, 2, '0'),
                            humanize.pad(dhms.SS, 2, '0')
                        ].join(':');
            }

            $('#upload_state_bar').html(html);
        },
        insertText: function (obj, str) {
            if (document.selection) {
                var sel = document.selection.createRange();
                sel.text = str;
            } else if (typeof obj.selectionStart === 'number' && typeof obj.selectionEnd === 'number') {
                var startPos = obj.selectionStart,
                    endPos = obj.selectionEnd,
                    cursorPos = startPos,
                    tmpStr = obj.value;
                obj.value = tmpStr.substring(0, startPos) + str + tmpStr.substring(endPos, tmpStr.length);
                cursorPos += str.length;
                obj.selectionStart = obj.selectionEnd = cursorPos;
            } else {
                obj.value += str;
            }
        },
        addToContent: function (fid) {
            var file = this.uploadedFiles[fid];
            var url = downloadUrlPrefix + file._hashName;
			var basename = /[^\/\\]*$/.exec(file.name);
			var size = humanize.filesize(file.size);

			if (basename.length == 0 || basename[0].length == 0) {
			    basename = '附件' + ext;
			}

			var urlname = url + '?attname=' + encodeURIComponent(basename);
            var html = '';

            if (/^\.(jpe?g|png|gif)$/.test(file._ext)) {
				html = '《图片：' + url + '，' + basename + '》';
            } else if (/^\.(mp4|m3u8|m4v|ts|mov|flv)$/.test(file._ext)) {
                html = '《视频流：' + urlname + '》';
            } else if (/^\.(mp3|wma|m4a|ogg)$/.test(file._ext)) {
                html = '《音频流：' + urlname + '》';
            } else {
                html = '《链接：' + urlname + '，' + basename + '（' + size + '）》';
            }

			this.insertText(document.getElementById('content'), html);
        },
        legacyMode: function () {
            $('#file').toggle();
            $('#upload').toggle();
            $('#to_legacy_mode').toggle();
            $('#to_modern_mode').toggle();
            $('#file_list').toggle();
            $('#legacy_mode_form').toggle();

            localStorage.uploadLegacyMode = ('1' == localStorage.uploadLegacyMode) ? '0' : '1';
        }
    };
    var downloadUrlPrefix = 'http://hu60.bj.bcebos.com/';
    var uploader = new baidubce.bos.Uploader({
        dragdrop: true, // 开启可拖曳上传
        drop_element: 'file_drop_area', // 拖曳上传区域元素的ID，拖曳文件或文件夹后可触发上传
        browse_button: '#file',
        bos_bucket: 'hu60',
        bos_endpoint: location.protocol + '//bj.bcebos.com',
        multi_selection: true,
        uptoken_url: '/q.php/api.baidubce.json',
        max_file_size: '0',
        bos_multipart_min_size: '1024G', // 禁止分片上传
        flash_swf_url: '../../js/moxie/bin/flash/Moxie.swf',
        max_retries: 999,                // 上传失败最大重试次数
        init: {
            FilesFilter: function (_, files) {
                var allowFiles = [];

                if (files.length) {
                    var length = files.length;

                    for (var i = 0; i < length; i++) {
                        var file = files[i];
                        fileList.setFid(file);

                        if (file.size > 10485760) {
                            fileList.add(file);
                            fileList.setState(file._id, '文件过大，无法上传。请选择 10MB 以内的文件。');
                            continue;
                        } else if (file.size < 1) {
                            fileList.add(file);
                            fileList.setState(file._id, '抱歉，不能上传空文件。');
                            continue;
                        }

                        allowFiles.push(file);
                    }
                }

                return allowFiles;
            },
            FilesAdded: function (_, files) {
                if (files.length) {
                    var length = files.length;

                    for (var i=0; i<length; i++) {
                        var file = files[i];
                        fileList.add(file);
                    }

                    // 为了保证file变量的一致性，使用串行方式进行md5计算

                    var md5PosEnd = files.length - 1;
                    var md5Pos = 0;

                    computeMd5();

                    function computeMd5() {
                        var file = files[md5Pos];

                        fileList.setState(file._id, '计算md5中...');

                        file._md5sum = baidubce.utils.md5sum(file);

                        file._md5sum.done(function () {
                            fileList.setState(file._id, '待上传');

                            if (md5Pos < md5PosEnd) {
                                md5Pos++;
                                computeMd5();
                            }
                        });

                        file._md5sum.fail(function (result) {
                            fileList.setState(file._id, 'md5计算失败');
                        });
                    }
                }
            },
            Key: function (_, file) {
                var ext = /\.[a-zA-Z0-9_-]{1,10}$/.exec(file.name);

                file._ext = (null === ext) ? '.dat' : ext[0].toLowerCase();
                var type = file._ext.substr(1) + '/';

                var deferred = baidubce.sdk.Q.defer();

                file._md5sum.done(function (md5) {
                    file._hashName = 'file/hash/' + type + md5 + file.size + file._ext;
                    deferred.resolve(file._hashName);
                });

                file._md5sum.fail(function () {
                    file._hashName = 'file/uuid/' + type + file.uuid + file.size + file._ext;
                    deferred.resolve(file._hashName);
                });

                return deferred.promise;
            },
            BeforeUpload: function(_, file) {
                fileList.setState(file._id, '上传中...');
            },
            UploadProgress: function (_, file, progress, event) {
                fileList.setProgress(file._id, progress);
            },
            NetworkSpeed: function (_, bytes, time, pendings) {
                fileList.setSpeed(bytes, time, pendings);
            },
            FileUploaded: function (_, file, info) {
                var actionHtml = '<a href="' + downloadUrlPrefix + htmlSpecialChars(file._hashName) + '">下载地址</a> ' +
                        '<a href="#" onclick="fileList.addToContent(' + file._id + ');return false">添加附件</a>';

                fileList.fileUploaded(file);
                fileList.setState(file._id, '已完成');
                fileList.setAction(file._id, actionHtml);
            },
            Error: function (_, error, file) {
                var errorMessage = $.isPlainObject(error) ? JSON.stringify(error) : String(error);
                fileList.setState(file._id, '<span class="failure">出错：' + htmlSpecialChars(errorMessage) + "</span>");

                $('#upload').attr("disabled", false);
            }
        }
    });

    $('#upload').click(function () {
        uploader.start();
        $('#upload').attr("disabled", true);
    });

    $('#save').click(function () {
        var content = $('#content').val();

        if (0 == content.length) {
            alert('没有可暂存的内容。');
        } else if (confirm('将内容暂存到当前浏览器，下次打开本页时可以载入。')) {
            try {
                localStorage.savedTopicContent = content;
                $('#action_state').html('暂存成功');
            } catch (e) {
                $('#action_state').html('浏览器不支持web存储API');
            }
        }
    });

    $('#load').click(function () {
        try {
            var content = localStorage.savedTopicContent;

            if ('string' !== typeof content || 0 == content.length) {
                alert('没有可载入的内容。');
            } else if (confirm("载入上次暂存的内容（" + content.length + "字）：\n" + content.substr(0, 100) + (content.length > 100 ? '...' : ''))) {
                $('#content').val(content);
                $('#action_state').html('载入成功');
            }
        } catch (e) {
            $('#action_state').html('浏览器不支持web存储API');
        }

    });

    $('#finish').click(function () {
        fileList.back();
    });

    $('#legacy_mode_upload').click(function () {
        var url = document.location.href;
        var pos = url.indexOf('#');
        if (pos >=0) {
            url = url.substr(0, pos);
        }
        fileList.topic.uploadUrl = url;
        fileList.topic.content = $('#content').val();
        var form = document.querySelector('#legacy_mode_form');
        form.action += '#addfiles=' + encodeURIComponent(JSON.stringify(fileList.topic));
        form.submit();
    });

    // 对Date的扩展，将 Date 转化为指定格式的String
    Date.prototype.Format = function (fmt) { //author: meizz
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds() //秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    };

    // 定义获取和更新时间的函数
    function showTime() {
        var curTime = new Date();
        $("#date").html(curTime.Format('MM月dd日 hh:mm:ss 星期几不知道'));
        setTimeout("showTime()", 1000);
    }

    // 页面加载完成后执行
    $(function(){
        //加载保存的帖子内容
        if (location.hash.startsWith('#addfiles=')) {
            fileList.topic = JSON.parse(decodeURIComponent(location.hash.substr(10)));
            $('#content').val(fileList.topic.content);
        }

        if ('1' == localStorage.uploadLegacyMode) {
            fileList.legacyMode();
            // legacyMode()会反转状态，这里保持状态一致
            localStorage.uploadLegacyMode = '1';
        }

        //显示时间
        showTime();

        // 允许粘贴文件
        document.addEventListener('paste', function (event) {
            console.log('hello', event);
            var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
            var files = [];
            for (var i=0; i<clipboardData.items.length; i++) {
                var file = clipboardData.items[i];
                if (file.kind === 'file') {
                    var file = file.getAsFile();
                    if (file) {
                        uploader.addFile(file);
                    }
                }
            }
        });
    });

</script>
</body>
</html>
